//
// Created by wangwanlong on 2024/6/14.
//

#ifndef MCGPP_COARSEN_BASE_H
#define MCGPP_COARSEN_BASE_H

#include "graph.h"
#include "timer.h"
#include "coarsening_memento.h"
#include "graph_pruner.h"
#include "refiner_base.h"

namespace mcgpp {
  //缩合基类
  class CoarsenBase {
  public:
    CoarsenBase(ds::GenericGraph &graph) : _g(graph),
                                           _graph_pruner(graph.initialNumNodes()) {

    }
    virtual ~CoarsenBase()= default;

    //执行缩合
    void performContraction(IDType rep_node, IDType contracted_node) {
      //缩合两个节点
      _history.emplace_back(Memento{rep_node, contracted_node});
      _g.contract(rep_node, contracted_node);
      //移除单点边和平行边
      _graph_pruner.removeSingleNodeEdges(_g, _history.back());
      _graph_pruner.removeParallelEdges(_g, _history.back());
    }

    //还原
    void performUncontraction() {
      //还原平行边和但单点边
      _graph_pruner.restoreParallelEdges(_g, _history.back());
      _graph_pruner.restoreSingleEdges(_g, _history.back());
      //还原两个点
//      LOG<<"uncontract:"<<_history.back().contraction_memento.u<<_history.back().contraction_memento.v;

      _g.uncontract(_history.back().contraction_memento);
      _history.pop_back();

//      _g.check();
    }

    void coarsen(int limit) {
      coarsenImpl(limit);
    }


    virtual void  coarsenImpl(int limit){};
    virtual void  uncoarsenImpl(RefinerBase& refiner){};
    virtual void  uncoarsenImpl(RefinerBase& refiner,Metrics& obj){};


    ds::GenericGraph &_g;
    std::vector<CoarseningMemento> _history;//记录缩合历史
    std::vector<int>_current_level_total_node_num;//保存每一轮缩合后的顶点数目
    GraphPruner _graph_pruner;

  };
}
#endif //MCGPP_COARSEN_BASE_H
